Popular Searches
Popular Course Categories
Popular Courses

Understanding Cross-Site Scripting (XSS) and CSRF

Understanding Cross-Site Scripting (XSS) and CSRF

Web Application Authentication and Security

Understanding Cross-Site Scripting (XSS) and CSRF

Course: Advanced Java Training

Topic: Understanding Cross-Site Scripting (XSS) and Cross-Site Request Forgery (CSRF)

Course Link: Advanced Java Training Course

Demo Link: Register for a Course Demo

Website: JustAcademy Homepage


1. Introduction to Web Application Security

Web application security protects websites, user accounts, sensitive information, and server-side functionality from unauthorized access and malicious activity. Java web applications built with Servlets, JSP, JDBC, and databases must handle user input carefully, manage sessions securely, and verify that every request is legitimate.

Two important web security vulnerabilities are Cross-Site Scripting (XSS) and Cross-Site Request Forgery (CSRF). Although both can affect web applications and their users, they work differently.

  • XSS: Occurs when untrusted content is interpreted as executable code in a user's browser.
  • CSRF: Tricks an authenticated user's browser into submitting an unwanted request to a trusted application.

Understanding these vulnerabilities helps developers design safer login systems, forms, dashboards, payment pages, account settings, and administrative features.

2. Learning Objectives

  • Understand the meaning and impact of XSS and CSRF.
  • Identify the major types of Cross-Site Scripting.
  • Understand reflected, stored, and DOM-based XSS.
  • Recognize common situations that lead to XSS vulnerabilities.
  • Learn output encoding, input validation, and HTML sanitization.
  • Understand how CSRF exploits automatically submitted browser credentials.
  • Implement CSRF token validation in Java Servlets.
  • Use secure cookies, HTTPS, and appropriate HTTP methods.
  • Distinguish between XSS and CSRF prevention techniques.
  • Test Java web applications for common security weaknesses.

3. What Is Cross-Site Scripting (XSS)?

Cross-Site Scripting, commonly called XSS, is a web security vulnerability in which an application allows untrusted data to be interpreted as executable content in another user's browser. Attackers may exploit this weakness to manipulate page content, perform actions within a victim's authenticated session, or access information available to scripts in that page's security context.

XSS often occurs when an application displays user-controlled data without applying the correct output encoding or HTML sanitization for the destination context.

Example Scenario

Imagine a discussion website where users can publish comments. The application saves each comment in a database and displays it on a page. If the application treats a comment as executable HTML instead of ordinary text, an attacker may submit content that runs JavaScript in the browsers of people viewing the comment.

The problem is not simply that the user submitted suspicious text. The core problem is that the application rendered untrusted content in an unsafe context.

Potential Consequences of XSS

  • Manipulation of the page's visible content.
  • Unauthorized actions performed within the victim's active session.
  • Access to sensitive information available to page scripts.
  • Phishing interfaces displayed within a trusted website.
  • Redirection to untrusted websites.
  • Abuse of application functionality available to the victim.

HttpOnly cookies can reduce the risk of JavaScript reading session cookies, but they do not eliminate XSS. Malicious scripts may still be able to perform actions through the victim's browser while the session is active.

4. Types of Cross-Site Scripting

Type Description Example Situation
Reflected XSS Untrusted request data is included unsafely in an immediate server response. A search term is displayed on a results page without output encoding.
Stored XSS Malicious content is saved and later rendered unsafely for one or more users. A stored comment is displayed on a discussion page as executable markup.
DOM-Based XSS Client-side JavaScript uses untrusted data in an unsafe DOM operation. A script reads a URL fragment and inserts it into the page using an unsafe HTML sink.

4.1 Reflected XSS

Reflected XSS occurs when a request contains untrusted data and the server immediately includes that data in a response without suitable context-aware encoding. The vulnerability can be triggered when a victim follows a specially crafted link or submits malicious input to a vulnerable page.

Prevention: Encode data for the exact output context, avoid constructing HTML from untrusted strings, and validate URL parameters according to the application's expected format.

4.2 Stored XSS

Stored XSS occurs when untrusted content is saved in a database, content management system, comment field, profile description, or another persistent data store. The vulnerability affects users who later view the content.

For example, a course review or user profile may contain untrusted markup. If the application renders that content as active HTML without sanitization, every visitor to the affected page may be exposed.

Prevention: Apply context-appropriate output encoding whenever the stored data is displayed. If users are intentionally allowed to author limited HTML, sanitize it with a maintained HTML sanitizer and an explicit allowlist.

4.3 DOM-Based XSS

DOM-Based XSS occurs when client-side JavaScript reads untrusted data and passes it to an unsafe browser API. The issue can exist even if the server returns a page without directly reflecting the malicious data.

Potential sources include URL parameters, URL fragments, messages from other windows, and data received from external services. Dangerous sinks include assigning untrusted HTML to innerHTML or executing dynamically constructed code.

Prevention: Prefer safe DOM APIs such as textContent, avoid eval() for data processing, and validate untrusted values before using them in URLs or other sensitive browser operations.

5. Understanding Unsafe and Safe Output

One of the most important XSS prevention principles is to treat user-controlled information as data, not as executable code. The appropriate defense depends on where the data is placed: HTML text, an HTML attribute, JavaScript, CSS, or a URL.

Unsafe Java Example

String comment = request.getParameter("comment");

response.setContentType("text/html;charset=UTF-8");
response.getWriter().println(
    "<div>" + comment + "</div>"
);

This code inserts the submitted comment directly into an HTML response. If the comment contains markup or other content that the browser interprets as active HTML, the application may be vulnerable to XSS.

Safer Java Example Using an Output Encoder

For HTML text output, use a maintained encoder such as the OWASP Java Encoder rather than manually replacing a few characters.

import org.owasp.encoder.Encode;

// Obtain comment from a request or trusted data source.
String comment = request.getParameter("comment");

response.setContentType("text/html;charset=UTF-8");
response.getWriter().println(
    "<div>" + Encode.forHtml(comment) + "</div>"
);

The example assumes the OWASP Java Encoder dependency is included in the project. Encode.forHtml() is suitable for text placed between ordinary HTML tags. Other contexts require their corresponding encoding strategy.

Important Output Encoding Rules

  • Use HTML encoding for untrusted text displayed inside HTML elements.
  • Use the appropriate attribute encoding for ordinary quoted HTML attributes.
  • Use URL encoding for individual untrusted URL parameter values, and validate the destination URL.
  • Use context-aware JavaScript encoding when embedding data in JavaScript is unavoidable.
  • Avoid inserting untrusted data directly into CSS, event-handler attributes, script code, or other dangerous contexts.
  • Do not assume that HTML encoding is interchangeable with JavaScript, CSS, or URL encoding.

6. Input Validation and HTML Sanitization

Input validation checks whether incoming data matches the application's requirements. HTML sanitization removes unsafe markup when an application intentionally supports a restricted subset of HTML. These techniques serve different purposes and should not replace correct output encoding.

Input Validation Example

String username = request.getParameter("username");

if (username == null
        || !username.matches("[A-Za-z0-9_]{3,30}")) {
    response.sendError(
        HttpServletResponse.SC_BAD_REQUEST,
        "Invalid username format."
    );
    return;
}

This example is appropriate only if the application's username policy permits letters, numbers, and underscores. Validation rules should match the field's actual business requirements.

When to Use HTML Sanitization

If users are allowed to submit formatted descriptions or rich-text content, rejecting all HTML may not be practical. In such cases, use a maintained HTML sanitizer configured with a strict allowlist of supported tags, attributes, and URL schemes.

Do not use a simple regular expression or a few string replacements as a complete HTML sanitizer. Browser parsing rules are complex, and simplistic filters can be bypassed.

7. What Is Cross-Site Request Forgery (CSRF)?

Cross-Site Request Forgery, or CSRF, is a web security vulnerability in which an attacker tricks a user's browser into sending an unwanted request to an application where the user is already authenticated.

Browsers commonly attach session cookies to requests matching the cookie's scope. As a result, an application that relies only on a session cookie may be unable to distinguish a legitimate form submission from a forged request unless it implements additional protections.

Example Scenario

Suppose a user is logged in to a banking application. If the application accepts a money-transfer request based only on the user's session cookie and does not verify that the request originated from a legitimate application workflow, a malicious website may attempt to cause the user's browser to submit an unwanted transfer request.

The malicious website does not need to know the user's password. The risk comes from the browser automatically including authentication credentials with a request to the trusted application.

Potential Consequences of CSRF

  • Unauthorized changes to account settings.
  • Changing an email address or password where the application lacks adequate protections.
  • Submitting purchases or other transactions.
  • Changing user permissions through a vulnerable administrative workflow.
  • Performing other state-changing operations using the victim's privileges.

8. How CSRF Attacks Work

  1. The user signs in to a legitimate application.
  2. The application establishes an authenticated session, often represented by a session cookie.
  3. The user visits an untrusted page or interacts with attacker-controlled content.
  4. The untrusted page attempts to cause the browser to send a request to the legitimate application.
  5. If the browser includes the session cookie and the application does not adequately validate the request, the operation may succeed.
  6. The application performs an action that the user did not intend to authorize.

CSRF depends on the application's authentication and request-validation design. It is not the same as stealing a password or directly executing JavaScript in the target application.

9. Common CSRF Weaknesses

  • State-changing operations are available through GET requests.
  • POST requests do not require CSRF tokens or another suitable request-verification mechanism.
  • The server relies only on the session cookie to authorize state changes.
  • Applications do not validate submitted CSRF tokens on the server.
  • Cookie configuration is too permissive.
  • Sensitive operations lack appropriate authorization and confirmation controls.
  • Applications incorrectly trust the Referer or Origin header as their only defense without a broader threat assessment.

10. XSS vs. CSRF

Feature XSS CSRF
Full Form Cross-Site Scripting Cross-Site Request Forgery
Primary Weakness Untrusted content is executed or interpreted unsafely in a browser. Unwanted requests are accepted using the victim's authenticated browser session.
Typical Attacker Goal Run malicious script in the target site's browser context. Cause an authenticated user to perform an unintended action.
Common Cause Missing context-aware output encoding or unsafe DOM manipulation. Missing CSRF protection on state-changing requests.
Main Defenses Output encoding, safe DOM APIs, HTML sanitization where needed, and defense-in-depth controls. CSRF tokens, suitable framework protections, SameSite cookies, and request validation.
Does It Require a Logged-In User? Not always. Impact can vary with the application and victim. Often relies on the victim being authenticated to the target application.
Can One Affect the Other? XSS may allow attackers to bypass many CSRF defenses in the same origin. CSRF protections do not by themselves prevent XSS.

11. Preventing CSRF in Java Applications

One common approach is the synchronizer token pattern. The server creates an unpredictable token, associates it with the user's session, and includes it in state-changing forms. When the form is submitted, the server verifies that the submitted token matches the expected session token.

Step 1: Create a CSRF Token

import java.security.SecureRandom;
import java.util.Base64;

public final class CsrfTokenUtil {
    private static final SecureRandom RANDOM = new SecureRandom();

    private CsrfTokenUtil() {
    }

    public static String generateToken() {
        byte[] bytes = new byte[32];
        RANDOM.nextBytes(bytes);
        return Base64.getUrlEncoder()
                     .withoutPadding()
                     .encodeToString(bytes);
    }
}

This utility generates a cryptographically unpredictable token. Store the token on the server in the user's session and do not expose it through URLs or logs.

Step 2: Store the Token in the Session

HttpSession session = request.getSession(true);

String csrfToken = CsrfTokenUtil.generateToken();
session.setAttribute("csrfToken", csrfToken);

request.setAttribute("csrfToken", csrfToken);
request.getRequestDispatcher("/update-profile.jsp")
       .forward(request, response);

This code illustrates token creation and storage. In a real application, reuse a valid token for the session or generate and rotate tokens according to the application's security design. Ensure that the token is inserted into the page using context-safe output handling.

Step 3: Include the Token in a Form

For example, a JSP form can include the token as a hidden input. Escape the value for the HTML attribute context before rendering it. The example below uses the OWASP Java Encoder.

<%@ page import="org.owasp.encoder.Encode" %>

<form action="update-profile" method="post">
    <input type="hidden"
           name="csrfToken"
           value="<%= Encode.forHtmlAttribute(
               (String) request.getAttribute("csrfToken")
           ) %>">

    <label for="displayName">Display Name:</label>
    <input type="text" id="displayName" name="displayName"
           required>

    <button type="submit">Update Profile</button>
</form>

The form uses POST because updating a profile changes application state. The hidden token is not a password; its purpose is to prove that the request contains a value associated with the user's legitimate session workflow.

Step 4: Validate the CSRF Token in a Servlet

package com.example.security;

import java.io.IOException;
import java.security.MessageDigest;
import java.nio.charset.StandardCharsets;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;

@WebServlet("/update-profile")
public class UpdateProfileServlet extends HttpServlet {

    @Override
    protected void doPost(
            HttpServletRequest request,
            HttpServletResponse response)
            throws IOException {

        HttpSession session = request.getSession(false);

        if (session == null) {
            response.sendError(
                HttpServletResponse.SC_UNAUTHORIZED,
                "Please sign in first."
            );
            return;
        }

        String expectedToken =
            (String) session.getAttribute("csrfToken");

        String submittedToken =
            request.getParameter("csrfToken");

        if (!tokensMatch(expectedToken, submittedToken)) {
            response.sendError(
                HttpServletResponse.SC_FORBIDDEN,
                "Invalid CSRF token."
            );
            return;
        }

        String displayName = request.getParameter("displayName");

        if (displayName == null || displayName.isBlank()
                || displayName.length() > 100) {
            response.sendError(
                HttpServletResponse.SC_BAD_REQUEST,
                "Invalid display name."
            );
            return;
        }

        // Perform the authorized profile update here.
        // Use parameterized SQL and validate all business rules.

        response.setContentType("text/plain;charset=UTF-8");
        response.getWriter().println("Profile update accepted.");
    }

    private boolean tokensMatch(String expected, String submitted) {
        if (expected == null || submitted == null) {
            return false;
        }

        return MessageDigest.isEqual(
            expected.getBytes(StandardCharsets.UTF_8),
            submitted.getBytes(StandardCharsets.UTF_8)
        );
    }
}

Understanding the Code

  • The Servlet accepts state-changing requests through doPost().
  • getSession(false) checks for an existing session without creating a new one.
  • The expected token is retrieved from the server-side session.
  • The submitted token is read from the request and compared with the expected value.
  • Missing or mismatched tokens result in rejection.
  • The business operation is performed only after request verification and input validation succeed.

This example demonstrates the token-validation pattern rather than a complete production security framework. In a real application, use established framework support when available, apply authorization checks as well as CSRF checks, and ensure every relevant state-changing endpoint is protected.

12. Using CSRF Tokens with AJAX Requests

For asynchronous requests, the application can send the CSRF token in a custom HTTP header. The server must still validate the token against the expected session token.

fetch("/myapp/update-profile", {
    method: "POST",
    headers: {
        "Content-Type": "application/json",
        "X-CSRF-Token": csrfToken
    },
    body: JSON.stringify({
        displayName: "Example User"
    }),
    credentials: "same-origin"
});

The value of csrfToken must be obtained through a trusted application workflow. The server should read the X-CSRF-Token header and validate it using the same principle as a form token. Do not accept arbitrary cross-origin requests merely because they include a custom header.

13. SameSite Cookies and Other CSRF Defenses

The SameSite cookie attribute controls when browsers send cookies in cross-site contexts. It can reduce CSRF risk, but it should be treated as an additional protection rather than a universal replacement for token validation.

Attribute Purpose Considerations
HttpOnly Prevents client-side JavaScript from directly reading the cookie. Helps limit cookie theft through some XSS attacks but does not stop XSS or CSRF by itself.
Secure Restricts cookie transmission to HTTPS connections. Use HTTPS throughout the application.
SameSite=Strict Restricts cookies in cross-site contexts more strongly. May affect legitimate cross-site navigation and sign-in workflows.
SameSite=Lax Allows cookies in certain cross-site top-level navigation contexts. Provides useful protection in many situations but does not replace all CSRF defenses.
SameSite=None Allows cross-site cookie use when browser requirements are satisfied. Typically requires Secure and increases the importance of other CSRF protections.

14. Additional CSRF Prevention Practices

  • Use framework-provided CSRF protection where available.
  • Require and validate CSRF tokens on state-changing requests.
  • Use POST, PUT, PATCH, or DELETE appropriately for state-changing operations instead of GET.
  • Configure session cookies with suitable Secure, HttpOnly, and SameSite attributes.
  • Validate Origin or Referer information as an additional signal when appropriate, not as the sole defense.
  • Require re-authentication or additional confirmation for especially sensitive operations.
  • Ensure every operation performs server-side authentication and authorization checks.
  • Do not expose CSRF tokens in URLs, logs, or third-party analytics.
  • Review client-side code that constructs requests using attacker-controlled URLs or parameters.
  • Remember that XSS can undermine many CSRF defenses; prevent both classes of vulnerability.

15. Content Security Policy (CSP)

Content Security Policy is a browser-enforced security mechanism that allows applications to restrict which sources can provide scripts, styles, images, and other resources. A carefully designed CSP can reduce the impact of certain XSS vulnerabilities, but it is not a substitute for safe output encoding and secure DOM operations.

Example CSP Header

response.setHeader(
    "Content-Security-Policy",
    "default-src 'self'; object-src 'none'; base-uri 'self'; " +
    "frame-ancestors 'self'; form-action 'self'"
);

This is an illustrative policy, not a universal configuration. Review the application's actual resources and deployment requirements before enforcing a policy. A stronger script policy often uses nonces or hashes and avoids unrestricted inline scripts. Test the policy before production deployment to avoid breaking legitimate application functionality.

16. Common Security Mistakes

Mistake Why It Is Risky Better Approach
Displaying user input directly as HTML. May cause injected markup or scripts to be interpreted by the browser. Use context-aware output encoding and safe DOM APIs.
Relying only on input validation for XSS prevention. Valid-looking input can still be unsafe in a particular output context. Validate input and encode output correctly.
Using regex to remove every possible malicious HTML pattern. HTML parsing is complex, and simplistic filters are unreliable. Use a maintained HTML sanitizer when rich HTML is required.
Using a CSRF token but never validating it. An attacker may submit a forged request without proving token possession. Validate the token on the server before performing the operation.
Assuming SameSite cookies solve every CSRF scenario. Some workflows and attack variations may not be covered. Combine suitable cookie settings with framework or token-based protection.
Changing application state through GET requests. Requests can be triggered by navigation, previews, or embedded resources. Use appropriate state-changing HTTP methods and CSRF defenses.
Relying entirely on CSP. Misconfiguration or gaps may leave XSS weaknesses exploitable. Use CSP as defense in depth, not as the primary XSS defense.
Checking authorization only in the interface. Direct requests may bypass hidden buttons or pages. Enforce authentication, authorization, and request validation on the server.

17. Testing for XSS and CSRF

Security testing should be performed only on applications and environments you are authorized to test. Use a development or staging environment and non-sensitive test accounts.

XSS Testing Checklist

  • Submit harmless test strings containing HTML-special characters and confirm they display as text when appropriate.
  • Test search results, comments, profile descriptions, and other user-controlled content.
  • Review JSP pages for direct insertion of untrusted values into HTML.
  • Inspect JavaScript for unsafe use of innerHTML, document.write(), and eval().
  • Check that any rich-text HTML is processed by a maintained sanitizer.
  • Verify that output encoding matches the destination context.
  • Review CSP headers as an additional security control.

CSRF Testing Checklist

  • Confirm that state-changing requests require the expected CSRF token or framework protection.
  • Submit a request with the token missing and verify that the server rejects it.
  • Submit a request with an invalid token and verify that no change occurs.
  • Confirm that a token from another session is not accepted.
  • Verify that sensitive GET endpoints do not change application state.
  • Inspect session cookie attributes in the browser's developer tools.
  • Confirm that server-side authorization checks are enforced even when a request has a valid CSRF token.
  • Test sensitive actions using separate accounts and verify that users cannot modify resources outside their permissions.

18. Mini Project: Securing a Java User Profile Application

Project Objective: Develop a Java web application that allows authenticated users to view and update their profiles while preventing common XSS and CSRF vulnerabilities.

Functional Requirements

  • Implement a secure login and logout process using Servlets.
  • Store user accounts in a database with securely hashed passwords.
  • Allow users to update permitted profile fields.
  • Validate all submitted data on the server.
  • Use context-aware output encoding when displaying profile information.
  • Use a maintained HTML sanitizer if limited rich-text content is supported.
  • Generate and validate CSRF tokens for state-changing forms.
  • Configure session cookies with appropriate security attributes.
  • Protect profile update operations with authentication and authorization checks.
  • Add automated tests for invalid input, missing tokens, and unauthorized requests.

Expected Outcome

User-provided content should be displayed safely, and profile updates should occur only when the request passes authentication, authorization, input validation, and CSRF checks. The application should reject invalid requests without exposing sensitive implementation details.

19. Interview Questions and Answers

Q1. What is Cross-Site Scripting?

XSS is a vulnerability that allows untrusted content to be interpreted as executable code or active markup in a user's browser.

Q2. What are the main types of XSS?

The common categories are reflected XSS, stored XSS, and DOM-based XSS.

Q3. What is the most important defense against XSS?

Use context-aware output encoding, safe DOM APIs, and appropriate HTML sanitization when users are allowed to submit rich HTML.

Q4. Does validating input alone prevent XSS?

No. Input validation is useful but does not replace output encoding or sanitization appropriate to the output context.

Q5. What is CSRF?

CSRF is a vulnerability in which an attacker tricks a user's browser into submitting an unwanted request to an application where the user is authenticated.

Q6. Why are CSRF tokens useful?

A server-validated CSRF token helps establish that a state-changing request includes a secret value associated with the legitimate application session or workflow.

Q7. What is the difference between XSS and CSRF?

XSS involves unsafe execution or interpretation of content in a browser, while CSRF involves forged requests that exploit an authenticated browser session.

Q8. Does HttpOnly prevent XSS?

No. HttpOnly prevents JavaScript from directly reading the associated cookie, but malicious scripts may still perform actions in the victim's browser.

Q9. Does SameSite completely eliminate CSRF?

No. SameSite cookies reduce certain cross-site request risks, but applications should use appropriate framework or token-based protection and validate state-changing requests.

Q10. Why should GET requests not modify application state?

GET is intended for retrieving resources. State-changing GET endpoints can be triggered by navigation or embedded requests and make CSRF prevention more difficult.

Q11. Can CSP replace output encoding?

No. CSP is an additional security layer and should not replace context-aware output encoding, safe DOM manipulation, or HTML sanitization.

Q12. Can XSS bypass CSRF protection?

In many cases, yes. Script executing in the trusted application's origin may be able to access CSRF tokens or submit requests that include them, which is why both vulnerabilities must be addressed.

20. Quick Revision

Concept Key Point
XSS Untrusted content is interpreted unsafely in a browser.
Reflected XSS Untrusted request data is reflected in an unsafe response.
Stored XSS Untrusted content is saved and later rendered unsafely.
DOM-Based XSS Client-side code places untrusted data into an unsafe DOM operation.
Output Encoding Converts data into a safe representation for a specific output context.
HTML Sanitization Removes unsafe markup when restricted user-authored HTML must be supported.
CSRF Causes a victim's authenticated browser to submit an unwanted request.
CSRF Token A value validated by the server to help verify state-changing requests.
SameSite Cookie attribute that restricts sending cookies in certain cross-site contexts.
CSP A browser-enforced policy that restricts permitted content sources.

21. Conclusion

Cross-Site Scripting and Cross-Site Request Forgery are important security risks for Java web applications. XSS can arise when untrusted data is rendered as active content, while CSRF can arise when a server accepts an unwanted state-changing request from an authenticated browser without adequate request verification.

Developers can reduce these risks by applying context-aware output encoding, using safe DOM APIs, sanitizing permitted rich HTML, validating CSRF tokens, configuring secure cookies, using appropriate HTTP methods, and enforcing authentication and authorization on the server. Security testing should cover both normal and malicious request scenarios throughout development.


Additional Security Resources

XSS Prevention: OWASP Cross-Site Scripting Prevention Cheat Sheet

CSRF Prevention: OWASP Cross-Site Request Forgery Prevention Cheat Sheet

Learn More with JustAcademy

Explore the Advanced Java Training Course to strengthen your understanding of Servlets, JSP, session management, and web application security.

Register for a Course Demo to learn more about the training program.

Visit the JustAcademy Homepage to explore additional courses and learning resources.

Previous Next
whatsapp